# -*- coding: utf-8 -*-
"""
@Time ： 2024/9/9 17:01
@Auth ： 周瑞东 Ryan.Zhou
@File ：config_manager.py
"""
import json
import os
from utils.global_state import GlobalState
'''
可以使用默认路径
也可以使用相对路径或项目的特定目录，动态设置配置文件的位置。例如，可以使用 Python 的 os.path 函数生成路径：


import os

# 获取当前脚本目录
script_dir = os.path.dirname(os.path.abspath(__file__))

# 配置文件存放在项目的 config 目录下
config_path = os.path.join(script_dir, 'config', 'user_settings.json')

config = ConfigManager(config_file=config_path)
'''


class ConfigManager:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(ConfigManager, cls).__new__(cls)
        return cls._instance

    def __init__(self, config_file=None):
        if not hasattr(self, '_initialized'):  # 确保只初始化一次
            self.__global_state = GlobalState()

            self.__full_path = (self.__global_state.common.proj_path +
                                self.__global_state.common.path_config_folder +
                                "user_settings.json")

            self.config_file = config_file if config_file else self.__full_path
            self.config_data = {}
            try:
                # 如果配置文件存在，读取它
                if os.path.exists(self.config_file):
                    with open(self.config_file, 'r', encoding='utf-8') as f:
                        self.config_data = json.load(f)
                else:
                    # 创建一个空的配置文件
                    self.write_to_file()
            except Exception as e:
                print(f"Error init configuration file: {e}")

            self._initialized = True

    '''
        获取特定 section 的内容
        读取异常处理方式：检查返回值是否为None
    '''
    '''
    这里使用一个字典，实现了类似ini中分节的功能
    原则上是，一个页面，一个分节
    get option 是获取一个section下的某一个特定option的内容
    例如，    "page_power": {
                "voltage_input": 140.0,
                "current_input": 7.0
            },
            从page_power中获取freq_value_input
            self.__config_man.get_option("page_e1682", "freq_value_input")

    读取异常处理方式：检查返回值是否为None

    '''
    def get_section(self, section_name):
        try:
            if section_name in self.config_data:
                data = self.config_data[section_name]
            else:
                return None
        except Exception as e:
            print(f"Error get configuration file: {e}")
            return None
        else:
            return data

    def get_option(self, section, option, default=None):
        try:
            """获取某个分节下的配置"""
            data = self.config_data.get(section, {}).get(option, default)
        except Exception as e:
            print(f"Error get configuration file: {e}")
            return None
        else:
            return data

    def set_section(self, section, data):
        """设置整个 section 的数据"""
        try:
            self.config_data[section] = data
            self.write_to_file()
        except Exception as e:
            print(f"Error set_section: {e}")
    '''
    单独设置某一个值
    section支持嵌套，即“database.host”
    '''
    def set_value(self, sections:str, key:str, value) -> bool:
        """设置指定 section 中的配置项，支持嵌套，不自动创建"""
        section_list = sections.split('.')  # 使用 '.' 来表示嵌套层级
        current_section = self.config_data

        # 逐级检查嵌套 section
        for section in section_list:
            if section in current_section:
                current_section = current_section[section]  # 切换到下一层
            else:
                print(f"Error: Section '{key}' does not exist.")  # 返回错误信息
                return False  # 指示更新失败

        current_section[key] = value  # 设置最终的键值对
        self.write_to_file()  # 保存文件
        return True  # 指示更新成功

    # try:
    #         """设置某个分节下的配置并保存"""
    #         if section not in self.config:
    #             self.config[section] = {}
    #         self.config[section][option] = value
    #         self.write_to_file()
    #     except Exception as e:
    #         print(f"Error set_value: {e}")

    '''
    保存到文件，在set_setting中已经调用该函数
    '''
    def write_to_file(self):
        """保存配置到文件"""
        with open(self.config_file, 'w') as f:
            json.dump(self.config_data, f, indent=4)
